from flask import jsonify
import logging
from werkzeug.exceptions import HTTPException
from sqlalchemy.exc import SQLAlchemyError
from jwt.exceptions import InvalidTokenError

# 获取日志器
logger = logging.getLogger('chat_app')

class APIError(Exception):
    """API自定义异常基类"""
    def __init__(self, message, status_code=400, error_code='API_ERROR', payload=None):
        super().__init__()
        self.message = message
        self.status_code = status_code
        self.error_code = error_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv['error'] = self.message
        rv['error_code'] = self.error_code
        rv['status_code'] = self.status_code
        return rv

class ResourceNotFoundError(APIError):
    """资源不存在异常"""
    def __init__(self, resource_type, resource_id):
        message = f"{resource_type} with ID {resource_id} not found"
        super().__init__(message, status_code=404, error_code='RESOURCE_NOT_FOUND')

class PermissionDeniedError(APIError):
    """权限不足异常"""
    def __init__(self, action):
        message = f"Permission denied for action: {action}"
        super().__init__(message, status_code=403, error_code='PERMISSION_DENIED')

class ValidationError(APIError):
    """数据验证异常"""
    def __init__(self, errors):
        message = "Validation failed"
        super().__init__(message, status_code=400, error_code='VALIDATION_ERROR', payload={'errors': errors})

def register_error_handlers(app):
    """注册全局错误处理器"""

    @app.errorhandler(APIError)
    def handle_api_error(error):
        response = jsonify(error.to_dict())
        response.status_code = error.status_code
        logger.error(f"API Error: {error.message} (Code: {error.error_code})")
        return response

    @app.errorhandler(HTTPException)
    def handle_http_exception(error):
        response = jsonify({
            'error': error.description,
            'error_code': f"HTTP_{error.code}",
            'status_code': error.code
        })
        response.status_code = error.code
        logger.warning(f"HTTP Error {error.code}: {error.description}")
        return response

    @app.errorhandler(SQLAlchemyError)
    def handle_sql_error(error):
        response = jsonify({
            'error': 'Database error occurred',
            'error_code': 'DATABASE_ERROR',
            'status_code': 500
        })
        response.status_code = 500
        logger.error(f"Database Error: {str(error)}", exc_info=True)
        return response

    @app.errorhandler(InvalidTokenError)
    def handle_jwt_error(error):
        response = jsonify({
            'error': 'Invalid authentication token',
            'error_code': 'JWT_ERROR',
            'status_code': 401
        })
        response.status_code = 401
        logger.warning(f"JWT Error: {str(error)}")
        return response

    @app.errorhandler(Exception)
    def handle_generic_exception(error):
        response = jsonify({
            'error': 'An unexpected error occurred',
            'error_code': 'INTERNAL_ERROR',
            'status_code': 500
        })
        response.status_code = 500
        logger.error(f"Unexpected Error: {str(error)}", exc_info=True)
        return response

    logger.info("Global error handlers registered successfully")